/******************************************************************************\
    TrayIcon.hpp contains a class of windows icon.
    Copyright (C) 2008  Victor Vinogradov (fly3333@gmail.com)

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
\******************************************************************************/

#pragma once

#include <windows.h>
//#include <shellapi.h>
#include ".\Object.hpp"

#define WM_SYSTEM_TRAY_NOTIFY ( WM_USER + 200 )

struct sNotifyIconData : public NOTIFYICONDATA
{
	sNotifyIconData()
	{
		memset( this, 0, sizeof( NOTIFYICONDATA ) );
		cbSize = sizeof( NOTIFYICONDATA );
	}
	sNotifyIconData( HWND window, UINT id, UINT flags, UINT callback_message, HICON icon, const TCHAR tool_tip[], DWORD state, DWORD state_mask, const TCHAR info[], UINT timeout, const TCHAR info_title[], DWORD info_flags )
	{
		cbSize = sizeof( NOTIFYICONDATA );
		hWnd = window;
		uID = id;
		uFlags = flags;
		uCallbackMessage = callback_message;
		hIcon = icon;
		strncpy( szTip, tool_tip, 63 )[ 63 ] = '\0';
#if _WIN32_IE >= 0x0500
		dwState = state;
		dwStateMask = state_mask;
		strncpy( szInfo, info, 255 )[ 255 ] = '\0';
      uTimeout = timeout;
		strncpy( szInfoTitle, info_title, 63 )[ 63 ] = '\0';
		dwInfoFlags = info_flags;
#endif
#if _WIN32_IE >= 0x0600
		memset( &guidItem, 0, sizeof( guidItem ) );
#endif
	}
};

class cSubTrayIcon : public cSubObject
{
	HWND Window;
	UINT Id;
public:
	cSubTrayIcon( HWND window, UINT id )
		: Window( window )
		, Id( id )
	{
	}
	~cSubTrayIcon()
	{
		Shell_NotifyIcon( NIM_DELETE, &sNotifyIconData( Window, Id, 0, 0, NULL, "", 0, 0, "", 0, "", 0 ) );
	}
	HWND GetWindow()
	{
		return Window;
	}
	UINT GetId()
	{
		return Id;
	}
};

class cTrayIcon : public cObject< cSubTrayIcon >
{
public:
	bool Create( HWND window, UINT id, UINT callback_message )
	{
		BOOL result = Shell_NotifyIcon( NIM_ADD, &sNotifyIconData( window, id, NIF_MESSAGE, callback_message, NULL, "", 0, 0, "", 0, "", 0 ) );
		if( result == FALSE )
			return false;
		cSubTrayIcon *sub_tray_icon;
		try
		{
			sub_tray_icon = new cSubTrayIcon( window, id );
		}
		catch( ... )
		{
			return false;
		}
		SwitchToSubObject( sub_tray_icon );
		return true;
	}
	void Destroy()
	{
		SwitchToSubObject( NULL );
	}
	bool SetToolTip( const char tool_tip[] )
	{
		return Shell_NotifyIcon( NIM_MODIFY, &sNotifyIconData( GetSubObject()->GetWindow(), GetSubObject()->GetId(), NIF_TIP, 0, NULL, tool_tip, 0, 0, "", 0, "", 0 ) ) != FALSE;
	}
	bool SetIcon( HICON icon )
	{
		return Shell_NotifyIcon( NIM_MODIFY, &sNotifyIconData( GetSubObject()->GetWindow(), GetSubObject()->GetId(), NIF_ICON, 0, icon, "", 0, 0, "", 0, "", 0 ) ) != FALSE;
	}
};
